package com.szholly.pro.watergas_server.ps.schedule;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import com.szholly.data.general.GlobalParameter;
import com.szholly.data.general.RowBase;
import com.szholly.pro.watergas_server.common.data.DataUtil;
import com.szholly.pro.watergas_server.common.util.RedisDbExecute;
import com.szholly.pro.watergas_server.common.util.RedisHelper;
import org.apache.log4j.Logger;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import lrq.common.MyLog;

public class DataAlarm implements Job {
	
	static Logger log;
	public static List<RowBase> StationList=null;
	public static String platCode = "4";  //平台编码 废气：4
	
	/**
	 * 判别连续超标报警
	 * gislin
	 * 2016年5月12日
	 */
	private void FindContinueDataAlarm(){
		log.info("开始生成超标信息");
		//查询站点与监测物信息
		String sql="select t.device_num,t1.station_category,t2.name as pollCode from BC_COLLECTION_INFO t"
				+ " left join BC_SITE_INFO t1 on t1.exp_no=t.site_id left join BC_SITE_POLL t2 on t2.site_id = t.site_id"
				+ " where t1.station_category='"+platCode+"'";
		List<RowBase> PollList= DataUtil.getSelectRows(sql, null);
		try{
			for(int i=0;i<PollList.size();i++){
				String mn =(String) PollList.get(i).get("DEVICE_NUM");
				String pollCode =(String) PollList.get(i).get("POLLCODE");
				String pollName = RedisHelper.getInstance().translationDictValue("MONITOR_PARAM", pollCode);
				
				if(pollName == null || pollName.equals("")){
					continue;
				}
				
				Double up = RedisHelper.getInstance().getPollAlarmUp(mn, pollCode);
				String key = "stationInfo:"+mn+":deviceInfo:"+pollCode+"_MEAS";
				Double value = RedisDbExecute.getDouble(key);
				SimpleDateFormat fm = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

				//是否配置该平台报警，只生成配置的平台报警信息
				String stationCategory = RedisHelper.getInstance().getStationTypeByMn(mn);
					
				if(stationCategory != null && ("1".equals(stationCategory)||"0".equals(stationCategory))){
					Date date = RedisDbExecute.getDate("stationInfo:"+mn+":deviceInfo:DataTime","yyyyMMddHHmmss");
					if(date == null)
					{
						date = new Date();
						log.info(mn+",deviceInfo:DataTime数值异常,请检查。");
					}
					createMulThreDataAlarm(mn,pollCode,value,0.0,date,"redis");
				}
				else{
					if(value!=null&&!"".equals(value)){
						if(value>0||value==0){	
							Date dataTime = RedisDbExecute.getDate("stationInfo:"+mn+":deviceInfo:DataTime_s");
							if(dataTime == null)
							{
								dataTime = new Date();
							}
							System.out.println("站点code："+mn+"；参数"+pollCode+"；时间"+fm.format(dataTime));
						}
					}
					if(up != null && value > up){
						processAlarm(mn, "Data", pollCode, value+"","超标","1","redis");
						log.info(mn+","+pollName+","+value+",超标");
					}
					else if(value < 0){
						processAlarm(mn, "Data", pollCode, value+"","异常","2","redis");
						log.info(mn+","+pollName+","+value+",异常");
					}
					else{
						ClearAlarm(mn, pollCode, "Data");
					}
				}
			}
		}catch (Exception e) {
			log.error("生成连续报警出错",e);
		}
	}
	
	/**
	 * 离线报警
	 * gislin
	 * 2016年5月14日
	 */
	private void FindContinueOffLineAlarm(){
		log.info("开始生成离线信息");

		String sql="select t.device_num,t1.station_category,t1.name from BC_COLLECTION_INFO t "
				  +" left join BC_SITE_INFO t1 on t1.exp_no=t.site_id where t1.station_category='"+platCode+"'";
		StationList=DataUtil.getSelectRows(sql, null);		
		for(int i=0;i<StationList.size();i++){
			String mn =(String) StationList.get(i).get("DEVICE_NUM");
			String channelId = RedisDbExecute.getString("stationInfo:"+mn+":deviceInfo:channelId");
			Date dataTime = RedisDbExecute.getDate("stationInfo:"+mn+":deviceInfo:DataTime_s");
			Date startAlarmTime = RedisDbExecute.getDate("stationInfo:"+mn+":alarmInfo:offLine:poll:netWork_startAlarmDate");
			String name =(String) StationList.get(i).get("NAME");
			
			//如果通道id为空 或者 数据时间为空 或者 数据时间和当前报警的时间的差值为0 就认为是掉线
			if(channelId == null || dataTime == null || (startAlarmTime!= null && dataTime.getTime() - startAlarmTime.getTime() == 0)){
				//掉线两分钟以上,才算掉线
				if(dataTime == null || (new Date().getTime() - dataTime.getTime()> 60000*10)){
					log.info(mn+","+name+",离线");
					processAlarm(mn, "offLine", "netWork", "离线","离线","4","redis");
				}
			}
			else{
				log.info(mn+","+name+",在线");
				ClearAlarm(mn, "netWork", "offLine");
			}
		}
	}

	/**
	 * 故障报警
	 * gislin
	 * 2016年5月14日
	 */
	private void FindContinueFaultAlarm(){
		log.info("开始生成故障信息");
		//查询站点与监测物信息
		String sql="select t.device_num,t1.station_category,t2.name as pollCode from BC_COLLECTION_INFO t"
				+ " left join BC_SITE_INFO t1 on t1.exp_no=t.site_id left join BC_SITE_POLL t2 on t2.site_id = t.site_id"
				+ " where t1.station_category='"+platCode+"'";
		List<RowBase> PollList=DataUtil.getSelectRows(sql, null);	
		try{
			for(int i=0;i<PollList.size();i++){
				String mn =(String) PollList.get(i).get("DEVICE_NUM");
				String pollCode =(String) PollList.get(i).get("POLLCODE");
				String pollName = RedisHelper.getInstance().translationDictValue("MONITOR_PARAM", pollCode);
		
				if(pollName == null || pollName.equals("")){
					continue;
				}

				Double errorCode = RedisDbExecute.getDouble("stationInfo:"+mn+":deviceInfo:"+pollCode+"_ERROR");
				
				if(errorCode != null && errorCode > 0){
					String errorText = RedisHelper.getInstance().getDeviceErrorText(mn, pollCode);
					processAlarm(mn, "Fault", pollCode, errorCode+"", errorText,"3","redis");
				}
				else{
					ClearAlarm(mn, pollCode, "Fault");
				}
			}
		}catch (Exception e) {
			log.error("生成故障信息出错",e);
		}
	}
	
	
	
	/**
	 * 生成超标报警（多阈值）
	 * 张文成
	 * 2016年11月07日
	 * @param alarmLevel
	 */
	public static void createMulThreDataAlarm(String mn,String pollCode,Double value,Double valueZS,Date date,String ALARM_DATASOURCE){
		String sql = "SELECT t.* from BC_POLL_THRESHOLD t "
				+ " where t.MN = '"+mn+"' and t.pollute_code = '"+pollCode+"'"
				+ " and t.alarm_thred_num not in('数据缺失','数据不变','日累计流量超标')"
				+ " order by to_number(density_alarm_uplimit) desc";
		List<GlobalParameter> parms = new ArrayList<GlobalParameter>();
		List<RowBase> rows = DataUtil.getSelectRows(sql, parms);
		if(rows.size()>0){
			for(int i=0;i<rows.size();i++){
				RowBase row = rows.get(i);
				//从上限低值，从高到低,逐个上下限比过去
				Double upLimit = row.getSafeDouble("density_alarm_uplimit");
				Double downLimit = row.getSafeDouble("density_alarm_dowmlimit");
				String alarm_threhold_guid = row.getSafeString("guid");
				//判断阈值类型，是实测值还是折算值		
				String threshold_Type = row.getSafeString("THRESHOLD_TYPE");	
				if("1".equals(threshold_Type))
				{
					value = valueZS;
				}
				
				if(value!=null&&!"".equals(value)){
					if(value > upLimit || value < downLimit)
					{    
						//只要有一个报警范围产生了报警，则跳过后续的上下限判断
						processMulThreAlarm(mn, "Data", pollCode, value+"","超标","1",upLimit,upLimit,alarm_threhold_guid,
								upLimit.toString(),downLimit.toString(),ALARM_DATASOURCE,date);
						i = rows.size();
					}
					else
					{
						//若遍历过去所有的报警范围，还无报警，则清空所有报警状态为已恢复
						if(i+1 == rows.size())
						{
							ClearMulThreAlarm(mn,pollCode,"1",date);
						}
					}
				}	
			}	
		}
	}
	
		
	/**
	 * 处理报警  （多阈值）
	 * 张文成
	 * 2016年11月05日
	 * @param mn
	 * @param alarmType
	 * @param pollCode
	 * @param alarmValue
	 */
	private static void processMulThreAlarm(String mn,String alarmType,String pollCode,String alarmValue,String alarmText,String alarmCode,
			double upLimit,double alarmLevel,String alarm_threhold_guid,String ALARM_UPLIMIT,String ALARM_DOWNLIMIT,
			String ALARM_DATASOURCE,Date date){
		//MN转换成站点ID与站点名称
		String stationCode = RedisHelper.getInstance().getStationCodeByMN(mn);
		String stationName = RedisHelper.getInstance().getStationNameByMN(mn);
		if(stationCode == null || stationName == null)
		{  
			log.info("处理超标报警时：mn:"+mn+"，转换成stationCode与stationName时出错，请检查redis数据");
			return;
		}
		
		//根据报警范围记录数添加alarmLevel,然后比较alarmLevel
		String sql = "select * from OP_ALAR_INFO where STATION_CODE = '"+stationCode+"' and PARAM = '"+pollCode+"'"
				+ " and IS_RECOVER = 0 and ALARM_LEVEL = @ALARM_LEVEL and TYPE = @TYPE and ALARM_DATASOURCE = @ALARM_DATASOURCE";
		List<GlobalParameter> parms = new ArrayList<GlobalParameter>();
		parms.add(new GlobalParameter("ALARM_LEVEL", alarmLevel));
		parms.add(new GlobalParameter("TYPE", alarmCode));
		parms.add(new GlobalParameter("ALARM_DATASOURCE", ALARM_DATASOURCE));
		List<RowBase> rows = DataUtil.getSelectRows(sql, parms);

		if(rows.size()==1){
			//如果有该报警范围内且状态为未恢复的记录的话，则更新数据库中的相应记录
			String guid = rows.get(0).getSafeString("guid");
			UpdateMulThreAlarm(guid,date);
			log.info("更新报警：alarmType:"+alarmType+",pollcode:"+pollCode+",guid:"+guid);
		}
		else if(rows.size() > 1)
		{
			//若有2条记录，则为不正常的情况，需要记录
			log.info("同一等级下有多条记录请注意：stationCode:"+stationCode+",pollcode:"+pollCode+",alarmValue:"+alarmValue);
		}
		else{
//			SimpleDateFormat fm = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//			String dataTimeStr = fm.format(date);
	
			//如果没有，则添加
			String guid = UUID.randomUUID().toString();
			AddMulThreAlarm(date,stationCode, alarmCode, pollCode, alarmValue,alarmText,alarmLevel,guid,ALARM_UPLIMIT,
					ALARM_DOWNLIMIT,ALARM_DATASOURCE,alarm_threhold_guid);
			//更新其他报警等级状态，低等级变为报警升级，高等级变为报警恢复
			UpdateMulThreOtherAlarmLevel(stationCode,pollCode,alarmCode,alarmLevel,ALARM_DATASOURCE,date);
			log.info("新增报警：alarmType:"+alarmType+",pollcode:"+pollCode);
			//新增报警记录的同时,构造报警内容,插入报警数据到MESSAGESEND表中
			//String pollName = RedisHelper.getInstance().translationDictValue("MONITOR_PARAM", pollCode);
			//String MESSAGECONTEXT = stationName + "：" + dataTimeStr + "，" + pollName + "监测值：" + alarmValue + "，已超标，请注意。";
			//CreateSendMessage(alarm_threhold_guid,guid,MESSAGECONTEXT);
		}
	}
	
	
	/**
	 * 更新数据库的报警信息  （多阈值）
	 * 张文成
	 * 2016年11月07日
	 * @param guid
	 * @param startAlarmTime
	 */
	private static void UpdateMulThreAlarm(String guid,Date date){		
		SimpleDateFormat fm = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dataTimeStr = fm.format(date);
		String updateAlarmSql = " update OP_ALAR_INFO set CONTINUE_TIME = ((to_date('"+dataTimeStr+"', 'yyyy-mm-dd hh24:mi:ss')"
				+ " - START_TIME)*24 * 60),UPDATETIME=sysdate where guid ='"+guid+"'";
		List<GlobalParameter> pc = new ArrayList<>();		
		DataUtil.ExecuteUpdateSql(updateAlarmSql, pc);
	}
	
	
	/**
	 * 增加报警  （多阈值）
	 * 张文成
	 * 2016年11月07日
	 * @param mn
	 * @param alarmType
	 * @param pollCode
	 * @param alarmValue
	 */
	private static void AddMulThreAlarm(Date dataTime,String stationCode,String alarmCode,String pollCode,String alarmValue,
			String alarmText,double alarmLevel,String guid,String ALARM_UPLIMIT,String ALARM_DOWNLIMIT,String ALARM_DATASOURCE,
			String alarm_threhold_guid) {
		String insertAlarmSql = " insert into OP_ALAR_INFO(GUID,TYPE,PARAM,START_TIME,ALARM_VALUE,STATION_CODE,ALARM_TEXT,"
				+ "UPDATETIME,ALARM_LEVEL,ALARM_UPLIMIT,ALARM_DOWNLIMIT,ALARM_DATASOURCE,IS_CREATEMESSAGE,ALARM_THREHOLD_GUID) "
				+ "values(@GUID,@TYPE,@PARAM,@START_TIME,@ALARM_VALUE,@STATION_CODE,@ALARM_TEXT,sysdate,@ALARM_LEVEL,"
				+ "@ALARM_UPLIMIT,@ALARM_DOWNLIMIT,@ALARM_DATASOURCE,'0',@ALARM_THREHOLD_GUID)";
		List<GlobalParameter> pc = new ArrayList<>();
		pc.clear();
		pc.add(new GlobalParameter("GUID", guid));
		pc.add(new GlobalParameter("TYPE", alarmCode));
		pc.add(new GlobalParameter("PARAM", pollCode));
		pc.add(new GlobalParameter("START_TIME",dataTime));
		pc.add(new GlobalParameter("ALARM_VALUE",alarmValue+""));
		pc.add(new GlobalParameter("ALARM_TEXT",alarmText));
		pc.add(new GlobalParameter("STATION_CODE",stationCode));
		pc.add(new GlobalParameter("ALARM_LEVEL",alarmLevel));
		pc.add(new GlobalParameter("ALARM_UPLIMIT",ALARM_UPLIMIT));
		pc.add(new GlobalParameter("ALARM_DOWNLIMIT",ALARM_DOWNLIMIT));
		pc.add(new GlobalParameter("ALARM_DATASOURCE",ALARM_DATASOURCE));
		pc.add(new GlobalParameter("ALARM_THREHOLD_GUID",alarm_threhold_guid));
		DataUtil.ExecuteUpdateSql(insertAlarmSql, pc);
	}
	
	/**
	 * 更新低等级报警的状态  （多阈值），更改状态为2：报警升级   0为最高等级报警，数值越大报警等级越小
	 * 张文成
	 * 2016年11月07日
	 * @param alarmLevel
	 */
	private static void UpdateMulThreOtherAlarmLevel(String stationCode,String pollCode,String alarmType,double alarmLevel,String ALARM_DATASOURCE
			,Date date){
		//IS_RECOVER :  0 未恢复  1已恢复 2报警升级
		SimpleDateFormat fm = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dataTimeStr = fm.format(date);
		
		//更新低等级报警状态为报警升级		
		String sql = "update OP_ALAR_INFO set IS_RECOVER = '2',CONTINUE_TIME = ((to_date('"+dataTimeStr+"', 'yyyy-mm-dd hh24:mi:ss')"
				+ " - START_TIME)*24 * 60), updatetime=sysdate "
				+ " where STATION_CODE = '"+stationCode+"' and PARAM = '"+pollCode+"'"
				+ " and ALARM_LEVEL < @ALARM_LEVEL and IS_RECOVER = 0 and TYPE = @TYPE and ALARM_DATASOURCE = @ALARM_DATASOURCE";			
		List<GlobalParameter> pc = new ArrayList<>();		
		pc.add(new GlobalParameter("ALARM_LEVEL", alarmLevel));
		pc.add(new GlobalParameter("TYPE", alarmType));
		pc.add(new GlobalParameter("ALARM_DATASOURCE", ALARM_DATASOURCE));
		DataUtil.ExecuteUpdateSql(sql, pc);
		
		//更新高等级报警状态为已恢复(已恢复的不要做处理)
		sql = "update OP_ALAR_INFO set IS_RECOVER = '1',CONTINUE_TIME = ((to_date('"+dataTimeStr+"', 'yyyy-mm-dd hh24:mi:ss')"
				+ " - START_TIME)*24 * 60),"
				+ "RECOVER_TIME=sysdate,updatetime=sysdate where "
				+ " STATION_CODE = '"+stationCode+"' and PARAM = '"+pollCode+"' and ALARM_LEVEL > @ALARM_LEVEL and "
				+ "IS_RECOVER != '1' and TYPE = @TYPE and ALARM_DATASOURCE = @ALARM_DATASOURCE";		
		pc = new ArrayList<>();	
		pc.clear();
		pc.add(new GlobalParameter("ALARM_LEVEL", alarmLevel));
		pc.add(new GlobalParameter("PARAM", pollCode));
		pc.add(new GlobalParameter("TYPE", alarmType));
		pc.add(new GlobalParameter("ALARM_DATASOURCE", ALARM_DATASOURCE));
		DataUtil.ExecuteUpdateSql(sql, pc);
	}
	
	
	/**
	 * 清除警报（多阈值，所有报警等级）
	 * 张文成
	 * 2016年6月12日
	 * @param mn
	 * @param pollCode
	 * @param lastAlarmId
	 * @param alarmType
	 */
	private static void ClearMulThreAlarm(String mn, String pollCode,String alarmType,Date date) {
		SimpleDateFormat fm = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dataTimeStr = fm.format(date);
		//MN转换成站点ID与站点名称
		String stationCode = RedisHelper.getInstance().getStationCodeByMN(mn);
		if(stationCode == null)
		{  
			log.info("清除超标报警时：mn:"+mn+"，转换成stationCode出错，请检查redis数据");
			return;
		}
		
		String clearAlarmSql = " update OP_ALAR_INFO set IS_RECOVER='1',CONTINUE_TIME = ((to_date('"+dataTimeStr+"', 'yyyy-mm-dd hh24:mi:ss') - START_TIME)*24 * 60) ,RECOVER_TIME=sysdate,updatetime=sysdate "
				 	+" where STATION_CODE =@STATION_CODE  and PARAM =@PARAM and TYPE = @TYPE and IS_RECOVER != '1'";
		List<GlobalParameter> pc = new ArrayList<>();
		pc.clear();
		pc.add(new GlobalParameter("STATION_CODE", stationCode));
		pc.add(new GlobalParameter("PARAM", pollCode));
		pc.add(new GlobalParameter("TYPE", alarmType));
		DataUtil.ExecuteUpdateSql(clearAlarmSql, pc);
	}
	
	
	
	/**
	 * 处理报警
	 * gislin
	 * 2016年6月13日
	 * @param mn
	 * @param alarmType
	 * @param pollCode
	 * @param alarmValue
	 */
	private void processAlarm(String mn,String alarmType,String pollCode,String alarmValue,String alarmText,String alarmCode,String dataSource){
		String lastAlarmId = RedisDbExecute.getString("stationInfo:"+mn+":alarmInfo:"+alarmType+":poll:"+pollCode+"_alarmId");
		String sql = " SELECT COUNT(1) FROM OP_ALAR_INFO WHERE GUID = '"+lastAlarmId+"' ";
		int count = DataUtil.getScaleInt(sql, null);
		if(count > 0){
			//如果有报警记录的id，就更新数据库中相应记录
			log.info("更新报警：alarmType:"+alarmType+",pollcode:"+pollCode+",alarmId:"+lastAlarmId);
			UpdateAlarm(mn, alarmType, pollCode, lastAlarmId);
		}
		else{
			//如果没有报警记录，则添加
			log.info("新增报警：alarmType:"+alarmType+",pollcode:"+pollCode);
			AddAlarm(mn, alarmType, alarmCode, pollCode, alarmValue,alarmText,dataSource);
			//在新增的报警记录上，做信息推送处理，添加报警数据从到MessageSend表中
		}
	}
	
	/**
	 * 更新数据库的报警信息
	 * gislin
	 * 2016年6月12日
	 * @param mn
	 * @param alarmType
	 * @param pollCode
	 * @param lastAlarmId
	 */
	private void UpdateAlarm(String mn,String alarmType,String pollCode,String lastAlarmId){
		Date lastAlarmTime = RedisDbExecute.getDate("stationInfo:"+mn+":alarmInfo:"+alarmType+":poll:"+pollCode+"_lastAlarmDate");
		Date dataTime = RedisDbExecute.getDate("stationInfo:"+mn+":deviceInfo:DataTime_s");
		
		if(dataTime == null || "offLine".equals(alarmType) || "dataLack".equals(alarmType) || "dataUC".equals(alarmType)){
			dataTime = new Date();
		}
		
		String updateAlarmSql = " update OP_ALAR_INFO set CONTINUE_TIME=@continueTime,UPDATETIME=sysdate where guid =@guid ";
		
		//如果当前的数据时间和上次的报警时间相隔太近，忽略，解决数据不更新的情况，比如客户端掉线
		if(dataTime.getTime() - lastAlarmTime.getTime() < 60000 ){
			return;
		}
		
		List<GlobalParameter> pc = new ArrayList<>();		
		Date startAlarmTime = RedisDbExecute.getDate("stationInfo:"+mn+":alarmInfo:"+alarmType+":poll:"+pollCode+"_startAlarmDate");
		int continueMinute = (int) ((dataTime.getTime() - startAlarmTime.getTime()) / 60000); //毫秒转成分钟
		RedisDbExecute.setDate("stationInfo:"+mn+":alarmInfo:"+alarmType+":poll:"+pollCode+"_lastAlarmDate",dataTime); //设置最后报警时间
		RedisDbExecute.setString("stationInfo:"+mn+":alarmInfo:"+alarmType+":poll:"+pollCode+"_alarmContinue", continueMinute+"");//设置报警持续时间
		pc.clear();
		pc.add(new GlobalParameter("continueTime", continueMinute));
		pc.add(new GlobalParameter("guid", lastAlarmId));
		DataUtil.ExecuteUpdateSql(updateAlarmSql, pc);
	}
	
	/**
	 * 增加报警
	 * gislin
	 * 2016年6月13日
	 * @param mn
	 * @param alarmType
	 * @param pollCode
	 * @param alarmValue
	 */
	private void AddAlarm(String mn,String alarmType,String alarmCode,String pollCode,String alarmValue,String alarmText,String dataSource) {
			String insertAlarmSql = " insert into OP_ALAR_INFO(GUID,TYPE,PARAM,START_TIME,ALARM_VALUE,STATION_CODE,ALARM_TEXT,UPDATETIME,ALARM_DATASOURCE) "
					+ "values(@GUID,@TYPE,@PARAM,@START_TIME,@ALARM_VALUE,@STATION_CODE,@ALARM_TEXT,sysdate,@DATASOURCE)";
			Date dataTime = RedisDbExecute.getDate("stationInfo:"+mn+":deviceInfo:DataTime_s");
			
			if(dataTime == null || "dataLack".equals(alarmType) || "dataUC".equals(alarmType)){
				dataTime = new Date();
			}
			
			List<GlobalParameter> pc = new ArrayList<>();
			String guid = UUID.randomUUID().toString();
			String stationCode=null;
			stationCode= RedisHelper.getInstance().getStationCodeByMN(mn);
			if(platCode.equals("3")){
				stationCode=mn;
			} 
			pc.clear();
			pc.add(new GlobalParameter("GUID", guid));
			pc.add(new GlobalParameter("TYPE", alarmCode));
			pc.add(new GlobalParameter("PARAM", pollCode));
			pc.add(new GlobalParameter("START_TIME",dataTime));
			pc.add(new GlobalParameter("ALARM_VALUE",alarmValue+""));
			pc.add(new GlobalParameter("ALARM_TEXT",alarmText));
			pc.add(new GlobalParameter("STATION_CODE",stationCode));
			pc.add(new GlobalParameter("DATASOURCE",dataSource));
			DataUtil.ExecuteUpdateSql(insertAlarmSql, pc);
			
			RedisDbExecute.setString("stationInfo:"+mn+":alarmInfo:"+alarmType+":poll:"+pollCode+"_alarmId",guid);
			RedisDbExecute.setDate("stationInfo:"+mn+":alarmInfo:"+alarmType+":poll:"+pollCode+"_lastAlarmDate",dataTime);
			RedisDbExecute.setDate("stationInfo:"+mn+":alarmInfo:"+alarmType+":poll:"+pollCode+"_startAlarmDate",dataTime);
			
	}

	/**
	 * 清除警报
	 * gislin
	 * 2016年6月12日
	 * @param mn
	 * @param pollCode
	 * @param lastAlarmId
	 * @param alarmType
	 */
	private void ClearAlarm(String mn, String pollCode,String alarmType) {
		String lastAlarmId = RedisDbExecute.getString("stationInfo:"+mn+":alarmInfo:"+alarmType+":poll:"+pollCode+"_alarmId");
		if(lastAlarmId == null){
			return;
		}
		String clearAlarmSql = " update OP_ALAR_INFO set IS_RECOVER='1',CONTINUE_TIME=@CONTINUE_TIME,RECOVER_TIME=@RECOVER_TIME,updatetime=sysdate where guid =@guid ";
		Date dataTime=new Date();
		Date startAlarmTime = RedisDbExecute.getDate("stationInfo:"+mn+":alarmInfo:"+alarmType+":poll:"+pollCode+"_startAlarmDate");
		int continueMinute = (int) ((dataTime.getTime() - startAlarmTime.getTime()) / 60000); //毫秒转成分钟
		List<GlobalParameter> pc = new ArrayList<>();
		RedisDbExecute.deleteKeys("stationInfo:"+mn+":alarmInfo:"+alarmType+":poll:"+pollCode+"_startAlarmDate");
		RedisDbExecute.deleteKeys("stationInfo:"+mn+":alarmInfo:"+alarmType+":poll:"+pollCode+"_lastAlarmDate");
		RedisDbExecute.deleteKeys("stationInfo:"+mn+":alarmInfo:"+alarmType+":poll:"+pollCode+"_alarmId");
		RedisDbExecute.deleteKeys("stationInfo:"+mn+":alarmInfo:"+alarmType+":poll:"+pollCode+"_alarmContinue");
		pc.clear();
		pc.add(new GlobalParameter("guid", lastAlarmId));
		pc.add(new GlobalParameter("RECOVER_TIME", dataTime));
		pc.add(new GlobalParameter("CONTINUE_TIME", continueMinute));
		DataUtil.ExecuteUpdateSql(clearAlarmSql, pc);
	}
	
	
	/**
	 * 判别工业污染源（废水废气）数据缺失，频次为2小时一次 
	 * wencheng
	 * 2017年6月10日
	 */
	private void FindIPSDataLack(){
		try{
	        //循环站点  
			log.info("开始生成数据缺失信息");
	        String sql = "select t1.id ,t1.device_num from BC_COLLECTION_INFO t1 "
	        		+ " left join BC_SITE_INFO t2 on t1.SITE_ID=t2.exp_no"
	        		+ " where t2.station_category = '"+platCode+"'"
	        		+ " order by t2.station_category";
			List<RowBase> rows = DataUtil.getSelectRows(sql, null); 
			if(rows.size()>0){
				for(int i=0;i<rows.size();i++){
					RowBase row = rows.get(i);
					String strMN = row.getSafeString("device_num");
					//查询小时数据是否有数据
				    sql = "select * from BD_MO_HOUR t where t.mn = '"+ strMN +"' and"
				    		+" t.datatime >= sysdate-2/24";
					List<RowBase> parmRows = DataUtil.getSelectRows(sql, null); 
					if(parmRows.size()==0){
						processAlarm(strMN, "dataLack","dataLack", "数据缺失","数据缺失", "7","小时数据");
					}
					else{
						ClearAlarm(strMN, "dataLack", "dataLack");
					}
				}
			}	
		}
		catch (Exception e) {
			log.error("生成工业污染源数据缺失信息出错",e);
		}
	}

	
	/**
	 * 判别工业污染源（废水废气）数据重复、污水流量重复2小时,频次2小时一次
	 * wencheng
	 * 2017年6月10日
	 */
	private void FindIPSDataUnchange(){
		try{
//			Calendar cal = Calendar.getInstance();
//			cal.setTime(date);
//	        if(cal.get(Calendar.MINUTE) != 30) 
//	        {
//	        	return;
//	        }
	        //循环站点    工业废水、工业废气所有站点  
			log.info("开始生成工业污染源数据不变信息");
	        String sql = "select t1.id,t1.device_num from BC_COLLECTION_INFO t1 "
	        		+ " left join BC_SITE_INFO t2 on t1.SITE_ID=t2.exp_no"
	        		+ " where t2.station_category = '"+platCode+"'"
	        		+ " order by t2.station_category";
			List<RowBase> rows = DataUtil.getSelectRows(sql, null); 
			if(rows.size()>0){
				for(int i=0;i<rows.size();i++){
					RowBase row = rows.get(i);
					String strMN = row.getSafeString("device_num");
					//查询小时数据B01TOTAL是否有数据、大于0
				    sql = "select count(t.cou) as count from BD_MO_HOUR t where t.mn = '"+ strMN +"' and"
				    		+" t.datatime >= sysdate-2/24 and t.parmname  = 'B01TOTAL' and t.cou > 0";
					List<RowBase> parmRows = DataUtil.getSelectRows(sql, null); 

					if(parmRows.size()>0&&parmRows.get(0).getSafeInt("count")>1){
						sql = "select t.*,t1.count as totalcount from (select t.parmname,count(t.parmname) as count from ("
								+" select t.parmname,round(t.avg) as avg from BD_MO_HOUR t where t.mn = '"+strMN+"' and"
								+" t.datatime >= sysdate-2/24 and t.parmname  in ('011','060') group by t.parmname,round(t.avg)"
                                +" union all (select t.parmname,round(t.avg,2) as avg from BD_MO_HOUR t where t.mn = '"+strMN+"' and"
								+" t.datatime >= sysdate-2/24 and t.parmname  in ('029','023','028') group by t.parmname,round(t.avg,2))) t"
								+" group by t.parmname ) t"
								+" left join ( select t.parmname,count(t.parmname) as count from BD_MO_HOUR t where t.mn = '"+strMN+"' and"
								+" t.datatime >= sysdate-2/24 and parmname in ('011','060','029','023','028')"
								+" group by t.parmname ) t1 on t1.parmname = t.parmname"
								+" where t1.count > 1";
						List<RowBase> reultRows = DataUtil.getSelectRows(sql, null); 
						if(reultRows.size()>0)
						{   
							for(int j=0;j<reultRows.size();j++){
								RowBase reultRow = reultRows.get(j);
								String strParmName = reultRow.getSafeString("parmname");
								if(reultRow.getSafeInt("COUNT")==1)
								{
									processAlarm(strMN, "dataUC",strParmName, "数据不变","数据不变", "8","小时数据");
								}else{
									ClearAlarm(strMN, "dataDFO",strParmName);
								}
							}
						}	
					}
				}	
			}
		}
		catch (Exception e) {
			log.error("生成工业污染源数据不变信息出错",e);
		}
	}
	
	/**
	 * 判别工业污染源（废水废气）日累计流量超标，频次为24小时一次
	 * wencheng
	 * 2017年6月10日
	 */
	private void FindIPSDataDayFlowOver(){
		try{
	        //循环站点    工业废水、工业废气所有站点  
			log.info("开始生成工业污染源日累计流量超标信息");
	        String sql = "select t1.id,t1.device_num,t2.station_category,t2.allow_day_emission from BC_COLLECTION_INFO t1 "
	        		+ " left join BC_SITE_INFO t2 on t1.SITE_ID=t2.exp_no"
	        		+ " where t2.station_category = '"+platCode+"'"
	        		+ " order by t2.station_category";
			List<RowBase> rows = DataUtil.getSelectRows(sql, null); 
			if(rows.size()>0){
				for(int i=0;i<rows.size();i++){
					RowBase row = rows.get(i);
					String strType = row.getSafeString("station_category");
					String strMN = row.getSafeString("device_num");
					Double allowDayEmissionD = row.getSafeDouble("allow_day_emission");
					
					if("4".equals(strType))  //废气
					{
						//查询烟气排放量日累积值
					    sql = "select t.cou from BD_MO_DAY t where t.mn = '"+ strMN +"' and"
					    		+" t.datatime > sysdate-1 and t.parmname  = 'AIRB01TOTAL' group by t.cou";
					}else{
						//查询废水排放量日累积值
					    sql = "select t.cou from BD_MO_DAY t where t.mn = '"+ strMN +"' and"
					    		+" t.datatime > sysdate-1 and t.parmname  = 'B01TOTAL' group by t.cou";
					}
					List<RowBase> parmRows = DataUtil.getSelectRows(sql, null); 
					if(parmRows.size()>0){
						if(parmRows.get(0).getSafeDouble("cou")>allowDayEmissionD){
							processAlarm(strMN, "dataDFO","dataDFO", "日累计流量超标","日累计流量超标", "9","天数据");
						}
						else{
							ClearAlarm(strMN, "dataDFO", "dataDFO");
						}						
					}
				}
			}	
		}
		catch (Exception e) {
			log.error("生成工业污染源日累计流量超标信息出错",e);
		}
	}
	
	@Override
	public void execute(JobExecutionContext arg0) throws JobExecutionException {
		
		if(log == null){
			log = MyLog.getLogger("alarmDataGenery");
		}		 
		try {			
//			FindContinueDataAlarm();
			FindContinueOffLineAlarm();
			FindContinueFaultAlarm();
			FindIPSDataLack();
			FindIPSDataUnchange();
			FindIPSDataDayFlowOver();
		} catch (Exception e) {
			log.error("生成报警信息出错",e);
		}
	}
	
	
	
	public void execute() throws JobExecutionException{
		execute(null);
	}
	
}
